package com.virjar.ratel.builder;

import com.virjar.ratel.allcommon.BuildEnv;
import com.virjar.ratel.allcommon.ReflectUtil;
import com.virjar.ratel.builder.helper.buildenv.JavaStringCompiler;
import com.virjar.ratel.builder.helper.buildenv.SerializeWriter;

import org.apache.commons.io.FileUtils;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.time.LocalDateTime;
import java.util.Map;

public class ClassTest2 {
    public static void main(String[] args) throws IllegalAccessException, IOException {
        Class<BuildEnv> buildEnvClass = BuildEnv.class;

        BuildEnv.DEBUG = false;
        String sourceCode = reGenPlainClass(buildEnvClass);
        System.out.println(sourceCode);

        Map<String, byte[]> compileResult = new JavaStringCompiler().compile(buildEnvClass.getSimpleName() + ".java", sourceCode);

        for (String str : compileResult.keySet()) {
            FileUtils.writeByteArrayToFile(new File("/Users/virjar/git/ratel-open/ratel-core/tmp", str + ".class"), compileResult.get(str));
        }
    }

    private static String reGenPlainClass(Class<?> clazz) throws IllegalAccessException {
        StringBuilder code = new StringBuilder("package ");

        code.append(clazz.getPackage().getName()).append(";\n");

        code.append("/**\n"
                + " * 请注意，当前class的所有字段必须是final的常量，在混淆工具链中本class会被删除\n * "
                + "\n * 当前为自动混淆产生class "
                + "\n * auto generated by ratel  on ")
                .append(LocalDateTime.now().toString())
                .append("\n */\n");

        code.append("public class ").append(clazz.getSimpleName()).append(" {\n");

        Field[] declaredFields = clazz.getFields();
        for (Field field : declaredFields) {
            if (!Modifier.isStatic(field.getModifiers())
                    || !Modifier.isPublic(field.getModifiers())
            ) {
                System.out.println("error field: " + field);
                continue;
            }

            code.append("   public static final ");
            code.append(field.getType().getName());
            code.append(" ").append(field.getName()).append(" = ");
            if (field.getType().equals(String.class)) {
                String str = ReflectUtil.getStaticFiled(clazz, field.getName());
                code.append(quote(str));
            } else {
                code.append((Object) ReflectUtil.getStaticFiled(clazz, field.getName()));
                if (field.getType().equals(long.class) || field.getType().equals(Long.class)) {
                    code.append("L");
                }
            }
            code.append(";\n");
        }
        code.append("}");

        return code.toString();
    }

    private static String quote(String input) {
        SerializeWriter serializeWriter = new SerializeWriter();
        serializeWriter.writeString(input);
        return serializeWriter.toString();
    }
}
